﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StringExtension.cs" company="Wedn.Net">
//   Copyright © 2014 Wedn.Net. All Rights Reserved.
// </copyright>
// <summary>
//   字符串拓展方法
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace System
{
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    /// <summary>
    /// 字符串拓展方法
    /// </summary>
    public static class StringExtension
    {
        #region 是否为安全SQL语句 +static bool IsSafeSql(this string input)
        /// <summary>
        /// 是否为安全SQL语句
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="input">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsSafeSql(this string input)
        {
            return !Regex.IsMatch(input, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }
        #endregion

        #region 判断指定字符串是否为合法IP地址 +static bool IsIpAddress(this string input)
        /// <summary>
        /// 判断指定字符串是否为合法IP地址
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="input">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsIpAddress(this string input)
        {
            return Regex.IsMatch(input, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }
        #endregion

        #region 判断指定字符串是否合法的日期格式 +static bool IsDateTime(this string input)
        /// <summary>
        /// 判断指定字符串是否合法的日期格式
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="input">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsDateTime(this string input)
        {
            DateTime dt;
            return DateTime.TryParse(input, out dt);
        }
        #endregion

        #region 判断指定的字符串是否为数字 +static bool IsInt(this string str)
        /// <summary>
        /// 判断指定的字符串是否为数字
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="str">要确认的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsInt(this string str)
        {
            return !string.IsNullOrEmpty(str) && Regex.IsMatch(str, "^-?\\d+$");
        }
        #endregion

        #region 判断指定的字符串是否为Url地址 +static bool IsUrl(this string str)
        /// <summary>
        /// 判断指定的字符串是否为Url地址
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="str">要确认的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsUrl(this string str)
        {
            return Regex.IsMatch(str, "(http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?");
        }
        #endregion

        #region 判断指定的字符串是否为合法Email +static bool IsEmail(this string str)
        /// <summary>
        /// 判断指定的字符串是否为合法Email
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="str">指定的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsEmail(this string str)
        {
            return Regex.IsMatch(str, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }
        #endregion

        #region 判断字符串是否为Null或者为空 +static bool IsNullOrEmpty(this string input)
        /// <summary>
        /// 判断字符串是否为Null或者为空
        /// </summary>
        /// <param name="input">要判断的字符串</param>
        /// <returns>是否为Null或者为空</returns>
        public static bool IsNullOrEmpty(this string input)
        {
            return string.IsNullOrEmpty(input);
        } 
        #endregion

        #region 判断字符串是否为Null或者为空字符组成 +static bool IsNullOrWhiteSpace(this string input)
        /// <summary>
        /// 判断字符串是否为Null或者为空字符组成
        /// </summary>
        /// <param name="input">要判断的字符串</param>
        /// <returns>否为Null或者为空字符组成</returns>
        public static bool IsNullOrWhiteSpace(this string input)
        {
            return string.IsNullOrWhiteSpace(input);
        } 
        #endregion



        #region 移除Html标记 +static string TrimHtml(this string html)
        /// <summary>
        /// 移除Html标记
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="html">包括HTML的源码</param>
        /// <returns>已经去除后的文字</returns>
        public static string TrimHtml(this string html)
        {
            // 删除脚本和嵌入式CSS   
            html = Regex.Replace(html, @"<script[^>]*?>.*?</script>", string.Empty, RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"<style[^>]*?>.*?</style>", string.Empty, RegexOptions.IgnoreCase);

            // 删除HTML   
            var regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
            html = regex.Replace(html, string.Empty);
            html = Regex.Replace(html, @"<(.[^>]*)>", string.Empty, RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"([\r\n])[\s]+", string.Empty, RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"-->", string.Empty, RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"<!--.*", string.Empty, RegexOptions.IgnoreCase);

            html = Regex.Replace(html, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            html = Regex.Replace(html, @"&#(\d+);", string.Empty, RegexOptions.IgnoreCase);

            return html.Replace("<", string.Empty).Replace(">", string.Empty).Replace("\r\n", string.Empty);
        }
        #endregion



        #region 返回字符串真实长度, 1个汉字长度为2
        /// <summary>
        /// 返回字符串真实长度, 1个汉字长度为2
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="str">The string.</param>
        /// <returns>System.Int32.</returns>
        public static int Length(this string str)
        {
            return string.IsNullOrEmpty(str) ? 0 : Encoding.UTF8.GetBytes(str).Length;
        }
        #endregion


        #region 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。
        /// <summary>
        /// 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。
        /// </summary>
        /// <param name="input">复合格式字符串。</param>
        /// <param name="args">一个对象数组，其中包含零个或多个要设置格式的对象。</param>
        /// <returns>format 的副本，其中的格式项已替换为 args 中相应对象的字符串表示形式。</returns>
        /// <exception cref="System.ArgumentNullException">input 或 args 为 null。</exception>
        /// <exception cref="System.FormatException">format 无效。- 或 -格式项的索引小于零或大于等于 args 数组的长度。</exception>
        public static string Format(this string input, params object[] args)
        {
            return string.Format(input, args);
        }
        #endregion

        #region Convert string type to other types

        #region String to Enum +static T ToEnum<T>(this string s) where T : struct
        /// <summary>
        /// String to Enum<see cref="T"/>
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="s"></param>
        /// <returns></returns>
        public static T ToEnum<T>(this string s) where T : struct
        {
            T result;
            Enum.TryParse(s, true, out result);
            return result;
        }
        #endregion

        #region String to Slug +static string ToSlug(this string input)
        /// <summary>
        /// String to Slug
        /// </summary>
        /// <remarks>
        ///  2013-11-18 18:53 Created By iceStone
        /// </remarks>
        /// <param name="input">String</param>
        /// <returns>Slug</returns>
        public static string ToSlug(this string input)
        {
            return string.IsNullOrEmpty(input)
                ? string.Empty : Regex.Replace(input.Trim().ToLower(), @"\s+", "-");
        }
        #endregion

        /// <summary>
        /// 转换成Key的形式
        /// </summary>
        /// <param name="input">输入</param>
        /// <returns>输出</returns>
        public static string ToKeyCase(this string input)
        {
            return string.IsNullOrEmpty(input)
                ? string.Empty : Regex.Replace(input.Trim().ToLower(), @"\s+", "_");
        }

        #endregion
    }
}
